﻿using Application.Common.Interface;
using Core.Extensions;
using Domain.Model;
using Microsoft.EntityFrameworkCore;

namespace Core.Persistence.Repository
{
    public class SelectorRepository : ISelectorRepository
    {
        private readonly WebScraperDbContext dbContext;
        public SelectorRepository(WebScraperDbContext dbContext)
        {
            this.dbContext = dbContext;
        }

        public async Task AddAsync(Selector sel)
        {
            var father = await GetByIdAsync(sel.FatherId);
            if (father is null)
                throw new ArgumentNullException(nameof(father));
            var parentPaths = father.ParentPaths;
            if (string.IsNullOrEmpty(parentPaths))
            {
                sel.ParentPaths = $"{father.Id}";
            }
            else
            {
                sel.ParentPaths = $"{father.ParentPaths},{father.Id}";
            }
            await dbContext.AddAsync(sel);
            await dbContext.SaveChangesAsync();
            //更新父亲节点的孩子集合
            if (string.IsNullOrEmpty(father.ChildrenIds))
            {
                father.ChildrenIds = $"{sel.Id}";
            }
            else
            {
                father.ChildrenIds += $",{sel.Id}";
            }
            dbContext.Update(father);
            await dbContext.SaveChangesAsync();
        }

        public async Task<Selector?> GetByIdAsync(int Id)
        {
            return await dbContext.selector.Where(s => s.Id == Id).FirstOrDefaultAsync();
        }
        public async Task<List<Selector>> GetByIdsAsync(IEnumerable<int> Ids)
        {
            return await dbContext.selector.Where(s => Ids.Contains(s.Id)).ToListAsync();
        }

        public async Task<List<Selector>> GetAllBySiteMapIdAsync(int siteMapId)
        {
            return await dbContext.selector.Where(s => s.SiteMapId == siteMapId).ToListAsync();
        }
        public async Task<Selector?> GetBySiteMapIdAsync(int siteMapId)
        {
            return await dbContext.selector.Where(s => s.SiteMapId == siteMapId && s.FatherId == 0).FirstOrDefaultAsync();
        }

        public async Task<List<Selector>> GetParentSelectorsById(int Id)
        {
            var sel = await GetByIdAsync(Id);
            return await GetParentSelectorsBySelectorAsync(sel);
        }

        public async Task<List<Selector>> GetParentSelectorsBySelectorAsync(Selector? sel)
        {
            var res = new List<Selector>();
            if (sel is null)
                return res;
            var parentIds = sel.ParentPaths.StringSplitGetList<int>();
            res = await GetByIdsAsync(parentIds);
            return res;
        }

        public async Task<List<Selector>> GetChildrenSelectorsByFatherIdAsync(int fatherId)
        {
            return await dbContext.selector.Where(s => s.FatherId == fatherId).ToListAsync();
        }

        public async Task<Selector> GetTreeSelectorByIdAsync(int Id)
        {
            var par = await GetByIdAsync(Id);
            par.Childrens = await GetChildrensAsync(Id);
            return par;
        }

        public async Task UpdateAsync(Selector sel)
        {
            sel.ParentSelectorNames = String.Join(",", sel.ParentSelectorNamesList);
            dbContext.Update(sel);
            await dbContext.SaveChangesAsync();
        }

        public async Task DeleteAsync(int Id)
        {
            var sel = await GetByIdAsync(Id);
            //删除所有孩子
            var delIds = sel.ChildrenIds.StringSplitGetList<int>();
            dbContext.RemoveRange(delIds.Select(id => new Selector() { Id = id }));
            dbContext.Remove(sel);
            await dbContext.SaveChangesAsync();
        }


        private async Task<List<Selector>> GetChildrensAsync(int fatherId)
        {
            var chilrens = await GetChildrenSelectorsByFatherIdAsync(fatherId);
            foreach (var it in chilrens??Enumerable.Empty<Selector>())
            {
                it.Childrens = await GetChildrensAsync(it.Id);
            }
            return chilrens;
        }

    }
}
